package org.lionsoul.websnail.worker;

import org.lionsoul.websnail.task.Task;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Spider worker builder - define the worker yourself
 *
 * @author chenxin<chenxin619315 @ gmail.com>
 */
public class SpiderWorkerBuilder {
    /**
     * busy sleep millisecond
     */
    private volatile int busySleepTime = -1;

    /**
     * core size of worker thread pool
     */
    private int coreThreadSize = -1;

    /**
     * max size of the worker thread pool
     */
    private int maxThreadSize = -1;

    /**
     * thread alive second of the worker thread pool
     */
    private int threadAliveSecond = -1;

    /**
     * working queue of the thread pool of the worker
     */
    private BlockingQueue<Runnable> threadPoolQueue = null;

    /**
     * task queue of the worker
     */
    private BlockingQueue<Task> taskQueue = null;

    public int getCoreThreadSize() {
        return coreThreadSize;
    }

    public SpiderWorkerBuilder setCoreThreadSize(int coreThreadSize) {
        this.coreThreadSize = coreThreadSize;
        return this;
    }

    public int getMaxThreadSize() {
        return maxThreadSize;
    }

    public SpiderWorkerBuilder setMaxThreadSize(int maxThreadSize) {
        this.maxThreadSize = maxThreadSize;
        return this;
    }

    public int getThreadAliveSecond() {
        return threadAliveSecond;
    }

    public SpiderWorkerBuilder setThreadAliveSecond(
            int threadAliveSecond) {
        this.threadAliveSecond = threadAliveSecond;
        return this;
    }

    public BlockingQueue<Runnable> getThreadPoolQueue() {
        return threadPoolQueue;
    }

    public SpiderWorkerBuilder setThreadPoolQueue(
            BlockingQueue<Runnable> threadPoolQueue) {
        this.threadPoolQueue = threadPoolQueue;
        return this;
    }

    public BlockingQueue<Task> getTaskQueue() {
        return taskQueue;
    }

    public SpiderWorkerBuilder setTaskQueue(BlockingQueue<Task> taskQueue) {
        this.taskQueue = taskQueue;
        return this;
    }

    public int getBusySleepTime() {
        return busySleepTime;
    }

    public SpiderWorkerBuilder setBusySleepTime(int busySleepTime) {
        this.busySleepTime = busySleepTime;
        return this;
    }

    /**
     * build the SpiderWorker according to the setting above
     *
     * @return SpiderWorker
     */
    public SpiderWorker build() {
        if (busySleepTime == -1) busySleepTime = 1500;
        if (coreThreadSize == -1) coreThreadSize = 15;
        if (maxThreadSize == -1) maxThreadSize = 30;
        if (threadAliveSecond == -1) threadAliveSecond = 5;

        if (threadPoolQueue == null) {
            threadPoolQueue = new ArrayBlockingQueue<Runnable>(10000);
        }

        if (taskQueue == null) {
            taskQueue = new LinkedBlockingQueue<Task>(10000);
        }

        //create and return a self defined SpiderWorker
        return new SpiderWorker(
                busySleepTime,
                coreThreadSize,
                maxThreadSize,
                threadAliveSecond,
                threadPoolQueue,
                taskQueue
        );
    }
}
